package com.youlai.boot.common.excel.impl;

import com.youlai.boot.common.excel.ExcelDataHandler;
import com.youlai.boot.common.excel.ExcelHandlerType;
import com.youlai.boot.common.excel.ExcelOperationService;
import com.youlai.boot.common.result.ExcelResult;
import com.youlai.boot.common.util.ExcelUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Excel操作服务实现类
 * 
 * @author Jason
 * @since 2024/05/18
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ExcelOperationServiceImpl implements ExcelOperationService {
    
    private final ApplicationContext applicationContext;
    
    /**
     * 处理器缓存
     */
    private final Map<String, ExcelDataHandler<?>> handlerCache = new ConcurrentHashMap<>();
    
    @Override
    @SuppressWarnings({"unchecked", "rawtypes"})
    public void exportExcel(Object query, String module, HttpServletResponse response) {
        try {
            // 获取处理器
            ExcelDataHandler handler = getHandler(module);
            
            // 获取数据
            List dataList = handler.getExportData(query);
            
            // 导出Excel
            ExcelUtils.exportExcel(
                    response,
                    dataList,
                    handler.getEntityClass(),
                    handler.getFileName(),
                    handler.getSheetName()
            );
        } catch (Exception e) {
            log.error("Excel导出失败: module={}, error={}", module, e.getMessage(), e);
            throw new RuntimeException("Excel导出失败: " + e.getMessage());
        }
    }
    
    @Override
    @SuppressWarnings({"unchecked", "rawtypes"})
    public ExcelResult importExcel(MultipartFile file, String module) {
        try {
            // 获取处理器
            ExcelDataHandler handler = getHandler(module);
            
            // 初始化结果
            ExcelResult result = new ExcelResult();
            
            // 读取Excel数据
            List dataList = ExcelUtils.importExcel(file, handler.getEntityClass());
            
            // 处理数据
            handler.handleImportData(dataList, result);
            
            return result;
        } catch (Exception e) {
            log.error("Excel导入失败: module={}, error={}", module, e.getMessage(), e);
            ExcelResult result = new ExcelResult();
            result.setSuccess(false);
            result.addErrorMsg("Excel导入失败: " + e.getMessage());
            return result;
        }
    }
    
    @Override
    @SuppressWarnings({"unchecked", "rawtypes"})
    public void downloadTemplate(String module, HttpServletResponse response) {
        try {
            // 获取处理器
            ExcelDataHandler handler = getHandler(module);
            
            // 获取模板数据
            List templateData = handler.getTemplateData();
            
            // 导出模板
            ExcelUtils.exportExcel(
                    response,
                    templateData,
                    handler.getEntityClass(),
                    handler.getFileName() + "模板",
                    handler.getSheetName()
            );
        } catch (Exception e) {
            log.error("Excel模板下载失败: module={}, error={}", module, e.getMessage(), e);
            throw new RuntimeException("Excel模板下载失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取Excel处理器
     * 
     * @param module 模块标识
     * @return Excel处理器
     */
    @SuppressWarnings("unchecked")
    private ExcelDataHandler<?> getHandler(String module) {
        return handlerCache.computeIfAbsent(module, type -> {
            Map<String, ExcelDataHandler> handlers = applicationContext.getBeansOfType(ExcelDataHandler.class);
            return handlers.values().stream()
                    .filter(handler -> {
                        ExcelHandlerType annotation = handler.getClass().getAnnotation(ExcelHandlerType.class);
                        return annotation != null && annotation.value().equals(type);
                    })
                    .findFirst()
                    .orElseThrow(() -> new RuntimeException("未找到模块[" + module + "]对应的Excel处理器"));
        });
    }
} 